﻿#ifndef _OI_PLSCANNER_IMAGEVIEWER_H_
#define _OI_PLSCANNER_IMAGEVIEWER_H_

#include "Appl/OiAppl.hpp"
#include <opencv2/opencv.hpp>

namespace Oi
{
    namespace View
    {
        class Raster;
        class Layer;
    }

    namespace PLScannerCore
    {
        class OI_PLSCANNER_CORE_API ImageViewer : public QGraphicsView
        {
            Q_OBJECT
        public:
            ImageViewer(QWidget* parent = NULL);

        public:
            ~ImageViewer();

        public:
            View::Raster* raster() const;
            View::Pixmap* pixmap() const;

        public:
            void setEditable(bool);
            bool isEditable() const;

        public:
            Core::PointMapPtr pointMap() const;
            Core::RangeMapPtr rangeMap() const;
            cv::Mat pointRemapMat() const;
            QVector<float> sampleZValues() const;

        public:
            QAction* colorModeAction() const;
            QAction* displayModeAction() const;
            QAction* fitZoomAction() const;

        public:
            View::Layer* dynamicLayer() const;

        public:
            OiProfiles profiles() const;

        public:
            bool isDisplay3D() const;

        public:
            QRectF rulerRect() const;
            QRectF imageRect() const;

            QPointF mapWidgetFromRulerPos(const QPointF);
            QPointF mapWidgetToRulerPos(const QPointF);

            QPointF mapSceneFromRulerPos(const QPointF);
            QPointF mapSceneToRulerPos(const QPointF);

            QPointF mapImageFromRulerPos(const QPointF);
            QPointF mapImageToRulerPos(const QPointF);

       signals:
            void axisHasChanged();
            void loadFile(const QString);

       signals:
            void hFlip();
            void vFlip();
            void rotateData();
            void cutData();
            void clearView();

        public slots:
            void zoomOut(double factor);

            void zoomFit();
            void zoomOrg();

        public slots:
            void showParameterPanel();
            void hideParameterPanel();

            void show3DLayer();
            void show2DLayer();

        public slots:
            void display(const Core::PointMapPtr& pointMap, int start = -1, int lines = -1);
            void display(const Core::RangeMapPtr& rangeMap, int start = -1, int lines = -1);
            void display(const QImage& image, int start = -1, int lines = -1);

        public slots:
            void clearAll();
            void blockContextMenuEvent();

        public slots:
            void invalidate();

        protected:
            bool event(QEvent* event);

        protected:
            void keyPressEvent(QKeyEvent *event);
            void keyReleaseEvent(QKeyEvent *event);
            void drawForeground(QPainter *painter, const QRectF &rect);
            void drawBackground(QPainter *painter, const QRectF &rect);
            void enterEvent(QEvent*);
            void leaveEvent(QEvent*);
            void mousePressEvent(QMouseEvent *event);
            void mouseReleaseEvent(QMouseEvent *event);
            void mouseMoveEvent(QMouseEvent *event);
            void mouseDoubleClickEvent(QMouseEvent *event);
            void contextMenuEvent(QContextMenuEvent *event);
            bool focusNextPrevChild(bool next) override;
            void wheelEvent(QWheelEvent *event);
            void resizeEvent(QResizeEvent *event);
            void paintEvent(QPaintEvent *event);
            void showEvent(QShowEvent *event);
            void hideEvent(QHideEvent *event);

        public:
            void dragEnterEvent(QDragEnterEvent* evt);
            void dragLeaveEvent(QDragLeaveEvent* evt);
            void dropEvent(QDropEvent* evt);

        private slots:
            void onActionTriggered();
            void onTimeout();

        public: 
            static ImageViewer* OiImageViewer();

        private:
            OI_DISABLE_COPY(ImageViewer);
            OI_DECLARE_IMPL(ImageViewer);
        };

    }
}

#endif
